'''
* This is the projet for Brtc LlmOps Platform
* @Author Leon-liao <liaosiliang@alltman.com>
* @Description //TODO 
* @File: api_tool_schema.py
* @Time: 2025/11/11
* @All Rights Reserve By Brtc
'''
from flask_wtf import FlaskForm
from marshmallow import Schema, fields, pre_dump
from wtforms import StringField
from wtforms.validators import DataRequired, Length, URL, Optional
from internal.exception.exception import ValidateErrorException
from pkg.paginator.paginator import PaginatorReq
from .schema import ListField
from internal.model import ApiToolProvider, ApiTool


class ValidateOpenAPISchema(FlaskForm):
    """检验Openapi 会犯字符串请求"""
    openapi_schema = StringField("openapi_schema", validators=[
                                DataRequired(message="openapi_schema字符串不能为空")])

class CreateApiToolReq(FlaskForm):
    """创建自定义API工具请求"""
    name = StringField("name", validators=[DataRequired(message="工具提供者名字不能为空"),
                                           Length(min=1, max=256, message="名字的长度控制在1-256 字节之间")])


    icon = StringField("icon", validators=[DataRequired(message="工具图标不能为空"),
                                        URL(message="工具提供者图标必须是url链接！")])
    openapi_schema = StringField("openapi_schema", validators=[
        DataRequired(message="openapi_schema字符串不能为空")])

    headers = ListField("headers", default=[])

    @classmethod
    def validate_headers(cls, form, field):
        """校验header 请求的数据是否正确, 涵盖列表校验，列表元素校验"""
        for header in field.data:
            if not isinstance(header, dict):
                raise ValidateErrorException("headers里面的每一个元素必须是字典")
            if(set(header.keys())) != {"key", "value"}:
                raise ValidateErrorException("headers 里面的每一个元素都必须包含key/value步允许其他属性！")


class GetApiToolProviderWithPageReq(PaginatorReq):
    """获取API工具提供者分页列表请求"""
    search_word = StringField("search_word", validators=[
        Optional()
    ])


class GetApiToolProvidersWithPageRsp(Schema):
    """获取API工具提供者分页列表数据响应"""
    id = fields.UUID()
    name = fields.String()
    icon = fields.String()
    description = fields.String()
    headers = fields.List(fields.Dict, dump_default=[])
    tools =   fields.List(fields.Dict, dump_default=[])
    created_at = fields.Integer(dump_default=0)

    @pre_dump
    def process_data(self, data:ApiToolProvider, **kwargs):
        tools = data.tools
        return {
            "id": data.id,
            "name": data.name,
            "icon": data.icon,
            "description": data.description,
            "headers": data.headers,
            "tools": [{
                "id":tool.id,
                "description":tool.description,
                "name":tool.name,
                "inputs":[{k:v for k,v in parameter.items() if k!= "in"} for parameter in tool.parameters]
            } for tool in tools],
        }


class UpdateApiToolProviderReq(FlaskForm):
    """更新API工具提供者请求"""
    """创建自定义API工具请求"""
    name = StringField("name", validators=[DataRequired(message="工具提供者名字不能为空"),
                                           Length(min=1, max=256, message="名字的长度控制在1-256 字节之间")])

    icon = StringField("icon", validators=[DataRequired(message="工具图标不能为空"),
                                           URL(message="工具提供者图标必须是url链接！")])
    openapi_schema = StringField("openapi_schema", validators=[
        DataRequired(message="openapi_schema字符串不能为空")])

    headers = ListField("headers", default=[])

    @classmethod
    def validate_headers(cls, form, field):
        """校验header 请求的数据是否正确, 涵盖列表校验，列表元素校验"""
        for header in field.data:
            if not isinstance(header, dict):
                raise ValidateErrorException("headers里面的每一个元素必须是字典")
            if (set(header.keys())) != {"key", "value"}:
                raise ValidateErrorException("headers 里面的每一个元素都必须包含key/value步允许其他属性！")


class GetApiToolProviderResp(Schema):
    """获取API工具提供者响应信息"""
    id = fields.UUID()
    name = fields.String()
    icon = fields.String()
    openapi_schema = fields.String()
    headers = fields.List(fields.Dict, dump_default=[])
    created_at = fields.Integer(dump_default=0)
    @pre_dump
    def process_data(self, data: ApiToolProvider, **kwargs):
        return {
            "id": data.id,
            "name": data.name,
            "icon": data.icon,
            "openapi_schema": data.openapi_schema,
            "headers": data.headers,
            "created_at": int(data.created_at.timestamp()),
        }


class GetApiToolResp(Schema):
    """获取API工具参数详情响应"""
    id = fields.UUID()
    name = fields.String()
    description = fields.String()
    inputs = fields.List(fields.Dict, dump_default=[])
    provider = fields.Dict()
    @pre_dump
    def process_data(self, data: ApiTool, **kwargs):
        provider = data.provider
        return {
            "id": data.id,
            "name": data.name,
            "description": data.description,
            "inputs": [{k: v for k, v in parameter.items() if k != "in"} for parameter in data.parameters],
            "provider": {
                "id": provider.id,
                "name": provider.name,
                "icon": provider.icon,
                "description": provider.description,
                "headers": provider.headers,
            }
        }